home *** CD-ROM | disk | FTP | other *** search
- > 7. Packages
-
-
-
- Packages are one of the four forms of program unit, of which programs can
- be composed. The other forms are subprograms, task units, and generic
- units.
-
-
- Packages allow the specification of groups of logically related entities.
- In their simplest form packages specify pools of common object and type
- declarations. More generally, packages can be used to specify groups of
- related entities including also subprograms that can be called from outside
- the package, while their inner workings remain concealed and protected from
- outside users.
-
-
- References: generic unit 12, program unit 6, subprogram 6, task unit 9,
- type declaration 3.3.1
-
- > 7.1 Package Structure
-
-
- A package is generally provided in two parts: a package specification and
- a package body. Every package has a package specification, but not all
- packages have a package body.
-
-
- package_declaration ::= package_specification;
-
- package_specification ::=
- package identifier is
- {basic_declarative_item}
- [private
- {basic_declarative_item}]
- end [package_simple_name]
-
- package_body ::=
- package body package_simple_name is
- [declarative_part]
- [begin
- sequence_of_statements
- [exception
- exception_handler
- {exception_handler}]]
- end [package_simple_name];
-
-
- The simple name at the start of a package body must repeat the package
- identifier. Similarly if a simple name appears at the end of the package
- specification or body, it must repeat the package identifier.
-
-
- If a subprogram declaration, a package declaration, a task declaration, or
- a generic declaration is a declarative item of a given package
- specification, then the body (if there is one) of the program unit declared
- by the declarative item must itself be a declarative item of the
- declarative part of the body of the given package.
-
- Notes:
-
-
- A simple form of package, specifying a pool of objects and types, does not
- require a package body. One of the possible uses of the sequence of
- statements of a package body is to initialize such objects. For each
- subprogram declaration there must be a corresponding body (except for a
- subprogram written in another language, as explained in section 13.9). If
- the body of a program unit is a body stub, then a separately compiled
- subunit containing the corresponding proper body is required for the
- program unit (see 10.2). A body is not a basic declarative item and so
- cannot appear in a package specification.
-
-
- A package declaration is either a library package (see 10.2) or a
- declarative item declared within another program unit.
-
-
- References: basic declarative item 3.9, body stub 10.2, declarative item
- 3.9, declarative part 3.9, exception handler 11.2, generic body 12.2,
- generic declaration 12.1, identifier 2.3, library unit 10.1, object 3.2,
- package body 7.3, program unit 6, proper body 3.9, sequence of statements
- 5.1, simple name 4.1, subprogram body 6.3, subprogram declaration 6.1,
- subunit 10.2, task body 9.1, task declaration 9.1, type 3.3
-
- > 7.2 Package Specifications and Declarations
-
-
- The first list of declarative items of a package specification is called
- the visible part of the package. The optional list of declarative items
- after the reserved word private is called the private part of the package.
-
-
- An entity declared in the private part of a package is not visible outside
- the package itself (a name denoting such an entity is only possible within
- the package). In contrast, expanded names denoting entities declared in
- the visible part can be used even outside the package; furthermore, direct
- visibility of such entities can be achieved by means of use clauses (see
- 4.1.3 and 8.4).
-
-
- The elaboration of a package declaration consists of the elaboration of its
- basic declarative items in the given order.
-
- Notes:
-
-
- The visible part of a package contains all the information that another
- program unit is able to know about the package. A package consisting of
- only a package specification (that is, without a package body) can be used
- to represent a group of common constants or variables, or a common pool of
- objects and types, as in the examples below.
-
-
- Example of a package describing a group of common variables:
-
- package PLOTTING_DATA is
- PEN_UP : BOOLEAN;
- CONVERSION_FACTOR,
- X_OFFSET, Y_OFFSET,
- X_MIN, Y_MIN,
- X_MAX, Y_MAX: REAL; -- see 3.5.7
-
- X_VALUE : array (1 .. 500) of REAL;
- Y_VALUE : array (1 .. 500) of REAL;
- end PLOTTING_DATA;
-
-
- Example of a package describing a common pool of objects and types:
-
- package WORK_DATA is
- type DAY is (MON, TUE, WED, THU, FRI, SAT, SUN);
- type HOURS_SPENT is delta 0.25 range 0.0 .. 24.0;
- type TIME_TABLE is array (DAY) of HOURS_SPENT;
-
- WORK_HOURS : TIME_TABLE;
- NORMAL_HOURS : constant TIME_TABLE :=
- (MON .. THU => 8.25, FRI => 7.0, SAT | SUN => 0.0);
- end WORK_DATA;
-
-
- References: basic declarative item 3.9, constant 3.2.1, declarative item
- 3.9, direct visibility 8.3, elaboration 3.9, expanded name 4.1.3, name 4.1,
- number declaration 3.2.2, object declaration 3.2.1, package 7, package
- declaration 7.1, package identifier 7.1, package specification 7.1, scope
- 8.2, simple name 4.1, type declaration 3.3.1, use clause 8.4, variable
- 3.2.1
-
- > 7.3 Package Bodies
-
-
- In contrast to the entities declared in the visible part of a package
- specification, the entities declared in the package body are only visible
- within the package body itself. As a consequence, a package with a package
- body can be used for the construction of a group of related subprograms (a
- package in the usual sense), in which the logical operations available to
- the users are clearly isolated from the internal entities.
-
-
- For the elaboration of a package body, its declarative part is first
- elaborated, and its sequence of statements (if any) is then executed. The
- optional exception handlers at the end of a package body service
- exceptions raised during the execution of the sequence of statements of the
- package body.
-
- Notes:
-
-
- A variable declared in the body of a package is only visible within this
- body and, consequently, its value can only be changed within the package
- body. In the absence of local tasks, the value of such a variable remains
- unchanged between calls issued from outside the package to subprograms
- declared in the visible part. The properties of such a variable are
- similar to those of an "own" variable of Algol 60.
-
-
- The elaboration of the body of a subprogram declared in the visible part of
- a package is caused by the elaboration of the body of the package. Hence a
- call of such a subprogram by an outside program unit raises the exception
- PROGRAM_ERROR if the call takes place before the elaboration of the package
- body (see 3.9).
-
-
- Example of a package:
-
- package RATIONAL_NUMBERS is
-
- type RATIONAL is
- record
- NUMERATOR : INTEGER;
- DENOMINATOR : POSITIVE;
- end record;
-
- function EQUAL(X,Y : RATIONAL) return BOOLEAN;
-
- function "/" (X,Y : INTEGER) return RATIONAL; -- to construct a rational number
-
- function "+" (X,Y : RATIONAL) return RATIONAL;
- function "-" (X,Y : RATIONAL) return RATIONAL;
- function "*" (X,Y : RATIONAL) return RATIONAL;
- function "/" (X,Y : RATIONAL) return RATIONAL;
- end;
-
- package body RATIONAL_NUMBERS is
-
- procedure SAME_DENOMINATOR (X,Y : in out RATIONAL) is
- begin
- -- reduces X and Y to the same denominator:
- ...
- end;
-
- function EQUAL(X,Y : RATIONAL) return BOOLEAN is
- U,V : RATIONAL;
- begin
- U := X;
- V := Y;
- SAME_DENOMINATOR (U,V);
- return U.NUMERATOR = V.NUMERATOR;
- end EQUAL;
-
- function "/" (X,Y : INTEGER) return RATIONAL is
- begin
- if Y > 0 then
- return (NUMERATOR => X, DENOMINATOR => Y);
- else
- return (NUMERATOR => -X, DENOMINATOR => -Y);
- end if;
- end "/";
-
- function "+" (X,Y : RATIONAL) return RATIONAL is ... end "+";
- function "-" (X,Y : RATIONAL) return RATIONAL is ... end "-";
- function "*" (X,Y : RATIONAL) return RATIONAL is ... end "*";
- function "/" (X,Y : RATIONAL) return RATIONAL is ... end "/";
-
- end RATIONAL_NUMBERS;
-
-
- References: declaration 3.1, declarative part 3.9, elaboration 3.1 3.9,
- exception 11, exception handler 11.2, name 4.1, package specification 7.1,
- program unit 6, program_error exception 11.1, sequence of statements 5.1,
- subprogram 6, variable 3.2.1, visible part 7.2
-
- > 7.4 Private Type and Deferred Constant Declarations
-
-
- The declaration of a type as a private type in the visible part of a
- package serves to separate the characteristics that can be used directly by
- outside program units (that is, the logical properties) from other
- characteristics whose direct use is confined to the package (the details of
- the definition of the type itself). Deferred constant declarations declare
- constants of private types.
-
-
- private_type_declaration ::=
- type identifier [discriminant_part] is [limited] private;
-
- deferred_constant_declaration ::=
- identifier_list : constant type_mark;
-
-
- A private type declaration is only allowed as a declarative item of the
- visible part of a package, or as the generic parameter declaration for a
- generic formal type in a generic formal part.
-
-
- The type mark of a deferred constant declaration must denote a private type
- or a subtype of a private type; a deferred constant declaration and the
- declaration of the corresponding private type must both be declarative
- items of the visible part of the same package. A deferred constant
- declaration with several identifiers is equivalent to a sequence of single
- deferred constant declarations as explained in section 3.2.
-
-
- Examples of private type declarations:
-
- type KEY is private;
- type FILE_NAME is limited private;
-
-
- Example of deferred constant declaration:
-
- NULL_KEY : constant KEY;
-
-
- References: constant 3.2.1, declaration 3.1, declarative item 3.9,
- deferred constant 7.4.3, discriminant part 3.7.1, generic formal part 12.1,
- generic formal type 12.1, generic parameter declaration 12.1, identifier
- 2.3, identifier list 3.2, limited type 7.4.4, package 7, private type
- 7.4.1, program unit 6, subtype 3.3, type 3.3, type mark 3.3.2, visible part
- 7.2
-
- > 7.4.1 Private Types
-
-
- If a private type declaration is given in the visible part of a package,
- then a corresponding declaration of a type with the same identifier must
- appear as a declarative item of the private part of the package. The
- corresponding declaration must be either a full type declaration or the
- declaration of a task type. In the rest of this section explanations are
- given in terms of full type declarations; the same rules apply also to
- declarations of task types.
-
-
- A private type declaration and the corresponding full type declaration
- define a single type. The private type declaration, together with the
- visible part, define the operations that are available to outside program
- units (see section 7.4.2 on the operations that are available for private
- types). On the other hand, the full type declaration defines other
- operations whose direct use is only possible within the package itself.
-
-
- If the private type declaration includes a discriminant part, the full
- declaration must include a discriminant part that conforms (see 6.3.1 for
- the conformance rules) and its type definition must be a record type
- definition. Conversely, if the private type declaration does not include a
- discriminant part, the type declared by the full type declaration (the full
- type) must not be an unconstrained type with discriminants. The full type
- must not be an unconstrained array type. A limited type (in particular a
- task type) is allowed for the full type only if the reserved word limited
- appears in the private type declaration (see 7.4.4).
-
-
- Within the specification of the package that declares a private type and
- before the end of the corresponding full type declaration, a restriction
- applies to the use of a name that denotes the private type or a subtype of
- the private type and, likewise, to the use of a name that denotes any type
- or subtype that has a subcomponent of the private type. The only allowed
- occurrences of such a name are in a deferred constant declaration, a type
- or subtype declaration, a subprogram specification, or an entry
- declaration; moreover, occurrences within derived type definitions or
- within simple expressions are not allowed.
-
-
- The elaboration of a private type declaration creates a private type. If
- the private type declaration has a discriminant part, this elaboration
- includes that of the discriminant part. The elaboration of the full type
- declaration consists of the elaboration of the type definition; the
- discriminant part, if any, is not elaborated (since the conforming
- discriminant part of the private type declaration has already been
- elaborated).
-
- Notes:
-
-
- It follows from the given rules that neither the declaration of a variable
- of a private type, nor the creation by an allocator of an object of the
- private type are allowed before the full declaration of the type.
- Similarly before the full declaration, the name of the private type cannot
- be used in a generic instantiation or in a representation clause.
-
-
- References: allocator 4.8, array type 3.6, conform 6.3.1, declarative item
- 3.9, deferred constant declaration 7.4.3, derived type 3.4, discriminant
- part 3.7.1, elaboration 3.9, entry declaration 9.5, expression 4.4, full
- type declaration 3.3.1, generic instantiation 12.3, identifier 2.3,
- incomplete type declaration 3.8.1, limited type 7.4.4, name 4.1, operation
- 3.3, package 7, package specification 7.1, private part 7.2, private type
- 7.4, private type declaration 7.4, record type definition 3.7,
- representation clause 13.1, reserved word 2.9, subcomponent 3.3, subprogram
- specification 6.1, subtype 3.3, subtype declaration 3.3.2, type 3.3, type
- declaration 3.3.1, type definition 3.3.1, unconstrained array type 3.6,
- variable 3.2.1, visible part 7.2
-
- > 7.4.2 Operations of a Private Type
-
-
- The operations that are implicitly declared by a private type declaration
- include basic operations. These are the operations involved in assignment
- (unless the reserved word limited appears in the declaration), membership
- tests, selected components for the selection of any discriminant,
- qualification, and explicit conversions.
-
-
- For a private type T, the basic operations also include the attributes
- T'BASE (see 3.3.3) and T'SIZE (see 13.7.2). For an object A of a private
- type, the basic operations include the attribute A'CONSTRAINED if the
- private type has discriminants (see 3.7.4), and in any case, the attributes
- A'SIZE and A'ADDRESS (see 13.7.2).
-
-
- Finally, the operations implicitly declared by a private type declaration
- include the predefined comparison for equality and inequality unless the
- reserved word limited appears in the private type declaration.
-
-
- The above operations, together with subprograms that have a parameter or
- result of the private type and that are declared in the visible part of the
- package, are the only operations from the package that are available
- outside the package for the private type.
-
-
- Within the package that declares the private type, the additional
- operations implicitly declared by the full type declaration are also
- available. However, the redefinition of these implicitly declared
- operations is allowed within the same declarative region, including between
- the private type declaration and the corresponding full declaration. An
- explicitly declared subprogram hides an implicitly declared operation that
- has the same parameter and result type profile (this is only possible if
- the implicitly declared operation is a derived subprogram or a predefined
- operator).
-
-
- If a composite type has subcomponents of a private type and is declared
- outside the package that declares the private type, then the operations
- that are implicitly declared by the declaration of the composite type
- include all operations that only depend on the characteristics that result
- from the private type declaration alone. (For example the operator < is
- not included for a one-dimensional array type.)
-
-
- If the composite type is itself declared within the package that declares
- the private type (including within an inner package or generic package),
- then additional operations that depend on the characteristics of the full
- type are implicitly declared, as required by the rules applicable to the
- composite type (for example the operator < is declared for a
- one-dimensional array type if the full type is discrete). These additional
- operations are implicitly declared at the earliest place within the
- immediate scope of the composite type and after the full type declaration.
-
-
- The same rules apply to the operations that are implicitly declared for an
- access type whose designated type is a private type or a type declared by
- an incomplete type declaration.
-
-
- For every private type or subtype T the following attribute is defined:
-
-
- T'CONSTRAINED Yields the value FALSE if T denotes an unconstrained
- nonformal private type with discriminants; also yields the
- value FALSE if T denotes a generic formal private type, and
- the associated actual subtype is either an unconstrained type
- with discriminants or an unconstrained array type; yields
- the value TRUE otherwise. The value of this attribute is of
- the predefined type BOOLEAN.
-
- Note:
-
-
- A private type declaration and the corresponding full type declaration
- define two different views of one and the same type. Outside of the
- defining package the characteristics of the type are those defined by the
- visible part. Within these outside program units the type is just a
- private type and any language rule that applies only to another class of
- types does not apply. The fact that the full declaration might implement
- the private type with a type of a particular class (for example, as an
- array type) is only relevant within the package itself.
-
-
- The consequences of this actual implementation are, however, valid
- everywhere. For example: any default initialization of components takes
- place; the attribute SIZE provides the size of the full type; task
- dependence rules still apply to components that are task objects.
-
-
- Example:
-
- package KEY_MANAGER is
- type KEY is private;
- NULL_KEY : constant KEY;
- procedure GET_KEY(K : out KEY);
- function "<" (X, Y : KEY) return BOOLEAN;
- private
- type KEY is new NATURAL;
- NULL_KEY : constant KEY := 0;
- end;
-
- package body KEY_MANAGER is
- LAST_KEY : KEY := 0;
- procedure GET_KEY(K : out KEY) is
- begin
- LAST_KEY := LAST_KEY + 1;
- K := LAST_KEY;
- end GET_KEY;
-
- function "<" (X, Y : KEY) return BOOLEAN is
- begin
- return INTEGER(X) < INTEGER(Y);
- end "<";
- end KEY_MANAGER;
-
- Notes on the example:
-
-
- Outside of the package KEY_MANAGER, the operations available for objects of
- type KEY include assignment, the comparison for equality or inequality, the
- procedure GET_KEY and the operator "<"; they do not include other
- relational operators such as ">=", or arithmetic operators.
-
-
- The explicitly declared operator "<" hides the predefined operator "<"
- implicitly declared by the full type declaration. Within the body of the
- function, an explicit conversion of X and Y to the type INTEGER is
- necessary to invoke the "<" operator of this type. Alternatively, the
- result of the function could be written as not (X >= Y), since the operator
- ">=" is not redefined.
-
-
- The value of the variable LAST_KEY, declared in the package body, remains
- unchanged between calls of the procedure GET_KEY. (See also the Notes of
- section 7.3.)
-
-
- References: assignment 5.2, attribute 4.1.4, basic operation 3.3.3,
- component 3.3, composite type 3.3, conversion 4.6, declaration 3.1,
- declarative region 8.1, derived subprogram 3.4, derived type 3.4, dimension
- 3.6, discriminant 3.3, equality 4.5.2, full type 7.4.1, full type
- declaration 3.3.1, hiding 8.3, immediate scope 8.2, implicit declaration
- 3.1, incomplete type declaration 3.8.1, membership test 4.5, operation 3.3,
- package 7, parameter of a subprogram 6.2, predefined function 8.6,
- predefined operator 4.5, private type 7.4, private type declaration 7.4,
- program unit 6, qualification 4.7, relational operator 4.5, selected
- component 4.1.3, subprogram 6, task dependence 9.4, visible part 7.2
-
- > 7.4.3 Deferred Constants
-
-
- If a deferred constant declaration is given in the visible part of a
- package then a constant declaration (that is, an object declaration
- declaring a constant object, with an explicit initialization) with the same
- identifier must appear as a declarative item of the private part of the
- package. This object declaration is called the full declaration of the
- deferred constant. The type mark given in the full declaration must
- conform to that given in the deferred constant declaration (see 6.3.1).
- Multiple or single declarations are allowed for the deferred and the full
- declarations, provided that the equivalent single declarations conform.
-
-
- Within the specification of the package that declares a deferred constant
- and before the end of the corresponding full declaration, the use of a name
- that denotes the deferred constant is only allowed in the default
- expression for a record component or for a formal parameter (not for a
- generic formal parameter).
-
-
- The elaboration of a deferred constant declaration has no other effect.
-
-
- The execution of a program is erroneous if it attempts to use the value of
- a deferred constant before the elaboration of the corresponding full
- declaration.
-
- Note:
-
-
- The full declaration for a deferred constant that has a given private type
- must not appear before the corresponding full type declaration. This is a
- consequence of the rules defining the allowed uses of a name that denotes a
- private type (see 7.4.1).
-
-
- References: conform 6.3.1, constant declaration 3.2.1, declarative item
- 3.9, default expression for a discriminant 3.7.1, deferred constant 7.4,
- deferred constant declaration 7.4, elaboration has no other effect 3.1,
- formal parameter 6.1, generic formal parameter 12.1 12.3, identifier 2.3,
- object declaration 3.2.1, package 7, package specification 7.1, private
- part 7.2, record component 3.7, type mark 3.3.2, visible part 7.2
-
- > 7.4.4 Limited Types
-
-
- A limited type is a type for which neither assignment nor the predefined
- comparison for equality and inequality is implicitly declared.
-
-
- A private type declaration that includes the reserved word limited declares
- a limited type. A task type is a limited type. A type derived from a
- limited type is itself a limited type. Finally, a composite type is
- limited if the type of any of its subcomponents is limited.
-
-
- The operations available for a private type that is limited are as given in
- section 7.4.2 for private types except for the absence of assignment and of
- a predefined comparison for equality and inequality.
-
-
- For a formal parameter whose type is limited and whose declaration occurs
- in an explicit subprogram declaration, the mode out is only allowed if this
- type is private and the subprogram declaration occurs within the visible
- part of the package that declares the private type. The same holds for
- formal parameters of entry declarations and of generic procedure
- declarations. The corresponding full type must not be limited if the mode
- out is used for any such formal parameter. Otherwise, the corresponding
- full type is allowed (but not required) to be a limited type (in
- particular, it is allowed to be a task type). If the full type
- corresponding to a limited private type is not itself limited, then
- assignment for the type is available within the package, but not outside.
-
-
- The following are consequences of the rules for limited types:
-
-
- - An explicit initialization is not allowed in an object declaration if
- the type of the object is limited.
-
-
- - A default expression is not allowed in a component declaration if the
- type of the record component is limited.
-
-
- - An explicit initial value is not allowed in an allocator if the
- designated type is limited.
-
-
- - A generic formal parameter of mode in must not be of a limited type.
-
- Notes:
-
-
- The above rules do not exclude a default expression for a formal parameter
- of a limited type; they do not exclude a deferred constant of a limited
- type if the full type is not limited. An explicit declaration of an
- equality operator is allowed for a limited type (see 6.7).
-
-
- Aggregates are not available for a limited composite type (see 3.6.2 and
- 3.7.4). Catenation is not available for a limited array type (see 3.6.2).
-
-
- Example:
-
- package I_O_PACKAGE is
- type FILE_NAME is limited private;
-
- procedure OPEN (F : in out FILE_NAME);
- procedure CLOSE(F : in out FILE_NAME);
- procedure READ (F : in FILE_NAME; ITEM : out INTEGER);
- procedure WRITE(F : in FILE_NAME; ITEM : in INTEGER);
- private
- type FILE_NAME is
- record
- INTERNAL_NAME : INTEGER := 0;
- end record;
- end I_O_PACKAGE;
-
- package body I_O_PACKAGE is
- LIMIT : constant := 200;
- type FILE_DESCRIPTOR is record ... end record;
- DIRECTORY : array (1 .. LIMIT) of FILE_DESCRIPTOR;
- ...
- procedure OPEN (F : in out FILE_NAME) is ... end;
- procedure CLOSE(F : in out FILE_NAME) is ... end;
- procedure READ (F : in FILE_NAME; ITEM : out INTEGER) is ... end;
- procedure WRITE(F : in FILE_NAME; ITEM : in INTEGER) is ... end;
- begin
- ...
- end I_O_PACKAGE;
-
- Notes on the example:
-
-
- In the example above, an outside subprogram making use of I_O_PACKAGE may
- obtain a file name by calling OPEN and later use it in calls to READ and
- WRITE. Thus, outside the package, a file name obtained from OPEN acts as a
- kind of password; its internal properties (such as containing a numeric
- value) are not known and no other operations (such as addition or
- comparison of internal names) can be performed on a file name.
-
-
- This example is characteristic of any case where complete control over the
- operations of a type is desired. Such packages serve a dual purpose. They
- prevent a user from making use of the internal structure of the type. They
- also implement the notion of an encapsulated data type where the only
- operations on the type are those given in the package specification.
-
-
- References: aggregate 4.3, allocator 4.8, assignment 5.2, catenation
- operator 4.5, component declaration 3.7, component type 3.3, composite type
- 3.3, default expression for a discriminant 3.7, deferred constant 7.4.3,
- derived type 3.4, designate 3.8, discriminant specification 3.7.1, equality
- 4.5.2, formal parameter 6.1, full type 7.4.1, full type declaration 3.3.1,
- generic formal parameter 12.1 12.3, implicit declaration 3.1, initial value
- 3.2.1, mode 12.1.1, object 3.2, operation 3.3, package 7, predefined
- operator 4.5, private type 7.4, private type declaration 7.4, record
- component 3.7, record type 3.7, relational operator 4.5, subcomponent 3.3,
- subprogram 6, task type 9.1 9.2, type 3.3
-
- > 7.5 Example of a Table Management Package
-
-
- The following example illustrates the use of packages in providing high
- level procedures with a simple interface to the user.
-
-
- The problem is to define a table management package for inserting and
- retrieving items. The items are inserted into the table as they are
- supplied. Each inserted item has an order number. The items are retrieved
- according to their order number, where the item with the lowest order
- number is retrieved first.
-
-
- From the user's point of view, the package is quite simple. There is a
- type called ITEM designating table items, a procedure INSERT for inserting
- items, and a procedure RETRIEVE for obtaining the item with the lowest
- order number. There is a special item NULL_ITEM that is returned when the
- table is empty, and an exception TABLE_FULL which is raised by INSERT if
- the table is already full.
-
-
- A sketch of such a package is given below. Only the specification of the
- package is exposed to the user.
-
-
- package TABLE_MANAGER is
-
- type ITEM is
- record
- ORDER_NUM : INTEGER;
- ITEM_CODE : INTEGER;
- QUANTITY : INTEGER;
- ITEM_TYPE : CHARACTER;
- end record;
-
- NULL_ITEM : constant ITEM :=
- (ORDER_NUM | ITEM_CODE | QUANTITY => 0, ITEM_TYPE => ' ');
-
- procedure INSERT (NEW_ITEM : in ITEM);
- procedure RETRIEVE(FIRST_ITEM : out ITEM);
-
- TABLE_FULL : exception; -- raised by INSERT when table full
- end;
-
-
- The details of implementing such packages can be quite complex; in this
- case they involve a two-way linked table of internal items. A local
- housekeeping procedure EXCHANGE is used to move an internal item between
- the busy and the free lists. The initial table linkages are established by
- the initialization part. The package body need not be shown to the users
- of the package.
-
-
- package body TABLE_MANAGER is
- SIZE : constant := 2000;
- subtype INDEX is INTEGER range 0 .. SIZE;
-
- type INTERNAL_ITEM is
- record
- CONTENT : ITEM;
- SUCC : INDEX;
- PRED : INDEX;
- end record;
-
- TABLE : array (INDEX) of INTERNAL_ITEM;
- FIRST_BUSY_ITEM : INDEX := 0;
- FIRST_FREE_ITEM : INDEX := 1;
-
- function FREE_LIST_EMPTY return BOOLEAN is ... end;
- function BUSY_LIST_EMPTY return BOOLEAN is ... end;
- procedure EXCHANGE (FROM : in INDEX; TO : in INDEX) is ... end;
-
- procedure INSERT (NEW_ITEM : in ITEM) is
- begin
- if FREE_LIST_EMPTY then
- raise TABLE_FULL;
- end if;
- -- remaining code for INSERT
- end INSERT;
-
- procedure RETRIEVE (FIRST_ITEM : out ITEM) is ... end;
-
- begin
- -- initialization of the table linkages
- end TABLE_MANAGER;
-
- > 7.6 Example of a Text Handling Package
-
-
- This example illustrates a simple text handling package. The users only
- have access to the visible part; the implementation is hidden from them in
- the private part and the package body (not shown).
-
-
- From a user's point of view, a TEXT is a variable-length string. Each text
- object has a maximum length, which must be given when the object is
- declared, and a current value, which is a string of some length between
- zero and the maximum. The maximum possible length of a text object is an
- implementation-defined constant.
-
-
- The package defines first the necessary types, then functions that return
- some characteristics of objects of the type, then the conversion functions
- between texts and the predefined CHARACTER and STRING types, and finally
- some of the standard operations on varying strings. Most operations are
- overloaded on strings and characters as well as on the type TEXT, in order
- to minimize the number of explicit conversions the user has to write.
-
-
- package TEXT_HANDLER is
- MAXIMUM : constant := SOME_VALUE; -- implementation-defined
- subtype INDEX is INTEGER range 0 .. MAXIMUM;
-
- type TEXT(MAXIMUM_LENGTH : INDEX) is limited private;
-
- function LENGTH (T : TEXT) return INDEX;
- function VALUE (T : TEXT) return STRING;
- function EMPTY (T : TEXT) return BOOLEAN;
-
- function TO_TEXT (S : STRING; MAX : INDEX) return TEXT; -- maximum length MAX
- function TO_TEXT (C : CHARACTER; MAX : INDEX) return TEXT;
- function TO_TEXT (S : STRING) return TEXT; -- maximum length S'LENGTH
- function TO_TEXT (C : CHARACTER) return TEXT;
-
- function "&" (LEFT : TEXT; RIGHT : TEXT) return TEXT;
- function "&" (LEFT : TEXT; RIGHT : STRING) return TEXT;
- function "&" (LEFT : STRING; RIGHT : TEXT) return TEXT;
- function "&" (LEFT : TEXT; RIGHT : CHARACTER) return TEXT;
- function "&" (LEFT : CHARACTER; RIGHT : TEXT) return TEXT;
-
- function "=" (LEFT : TEXT; RIGHT : TEXT) return BOOLEAN;
- function "<" (LEFT : TEXT; RIGHT : TEXT) return BOOLEAN;
- function "<=" (LEFT : TEXT; RIGHT : TEXT) return BOOLEAN;
- function ">" (LEFT : TEXT; RIGHT : TEXT) return BOOLEAN;
- function ">=" (LEFT : TEXT; RIGHT : TEXT) return BOOLEAN;
-
- procedure SET (OBJECT : in out TEXT; VALUE : in TEXT);
- procedure SET (OBJECT : in out TEXT; VALUE : in STRING);
- procedure SET (OBJECT : in out TEXT; VALUE : in CHARACTER);
-
- procedure APPEND (TAIL : in TEXT; TO : in out TEXT);
- procedure APPEND (TAIL : in STRING; TO : in out TEXT);
- procedure APPEND (TAIL : in CHARACTER; TO : in out TEXT);
-
- procedure AMEND (OBJECT : in out TEXT; BY : in TEXT; POSITION : in INDEX);
- procedure AMEND (OBJECT : in out TEXT; BY : in STRING; POSITION : in INDEX);
- procedure AMEND (OBJECT : in out TEXT; BY : in CHARACTER; POSITION : in INDEX);
-
- -- amend replaces part of the object by the given text, string, or character
- -- starting at the given position in the object
-
- function LOCATE (FRAGMENT : TEXT; WITHIN : TEXT) return INDEX;
- function LOCATE (FRAGMENT : STRING; WITHIN : TEXT) return INDEX;
- function LOCATE (FRAGMENT : CHARACTER; WITHIN : TEXT) return INDEX;
-
- -- all return 0 if the fragment is not located
-
- private
- type TEXT(MAXIMUM_LENGTH : INDEX) is
- record
- POS : INDEX := 0;
- VALUE : STRING(1 .. MAXIMUM_LENGTH);
- end record;
- end TEXT_HANDLER;
-
-
- Example of use of the text handling package:
-
-
- A program opens an output file, whose name is supplied by the string NAME.
- This string has the form
-
- [DEVICE :] [FILENAME [.EXTENSION]]
-
-
- There are standard defaults for device, filename, and extension. The
- user-supplied name is passed to EXPAND_FILE_NAME as a parameter, and the
- result is the expanded version, with any necessary defaults added.
-
-
- function EXPAND_FILE_NAME (NAME : STRING) return STRING is
- use TEXT_HANDLER;
-
- DEFAULT_DEVICE : constant STRING := "SY:";
- DEFAULT_FILE_NAME : constant STRING := "RESULTS";
- DEFAULT_EXTENSION : constant STRING := ".DAT";
-
- MAXIMUM_FILE_NAME_LENGTH : constant INDEX := SOME_APPROPRIATE_VALUE;
- FILE_NAME : TEXT(MAXIMUM_FILE_NAME_LENGTH);
-
- begin
-
- SET(FILE_NAME, NAME);
-
- if EMPTY(FILE_NAME) then
- SET(FILE_NAME, DEFAULT_FILE_NAME);
- end if;
-
- if LOCATE(':', FILE_NAME) = 0 then
- SET(FILE_NAME, DEFAULT_DEVICE & FILE_NAME);
- end if;
-
- if LOCATE('.', FILE_NAME) = 0 then
- APPEND(DEFAULT_EXTENSION, TO => FILE_NAME);
- end if;
-
- return VALUE(FILE_NAME);
-
- end EXPAND_FILE_NAME;
-